package org.wattdepot.gdata.kukuicup.updater.powerlastfewminutes;

import java.net.URL;
import org.wattdepot.client.WattDepotClient;
import org.wattdepot.gdata.kukuicup.service.GDataBatchRequest;
import org.wattdepot.gdata.kukuicup.service.GDataService;
import org.wattdepot.gdata.kukuicup.service.WattDepotService;
import org.wattdepot.gdata.kukuicup.updater.GDataTask;
import org.wattdepot.gdata.kukuicup.updater.RollingData;
import org.wattdepot.resource.sensordata.jaxb.SensorData;
import org.wattdepot.util.tstamp.Tstamp;

/**
 * Implements the task to obtain data on power levels every few seconds for the past few minutes.
 * @author Philip Johnson
 */
public class PowerLastFewMinutesTask extends GDataTask {
  
  /** Holds the 10 most recent power entries. */
  private RollingData rollingData = new RollingData(10);

  /**
   * Creates the task that gets woken up regularly (typically every 15 seconds). 
   * @param wattDepotService The WattDepot service configuration data. 
   * @param gdataService The gdata service configuration data.
   * @param spreadsheetURL The URL to the spreadsheet containing the data.
   * @param sourceName The WattDepot source of interest.
   * @param isVirtual True if the source is virtual.
   * @param row The row in the spreadsheet that this source's data appears in.
   */
  public PowerLastFewMinutesTask(WattDepotService wattDepotService, GDataService gdataService, 
      URL spreadsheetURL, String sourceName, boolean isVirtual, int row) {
    super(wattDepotService, gdataService, spreadsheetURL, sourceName, row, "PowerLastFewMinutes",
        isVirtual);
    String defaultTimestamp = 
      gdataService.makeLastUpdate(Tstamp.incrementDays(Tstamp.makeTimestamp(), -30));
    rollingData.initialize(defaultTimestamp, "0");
  }

  /**
   * Retrieve the power data from WattDepot and place it into the GData spreadsheet.
   */
  @Override
  public void run() {
    WattDepotClient client = this.wattDepotService.getClient();
    try {
      // We get the following values differently depending on whether the source is virtual.
      String power; 
      String powerTimestamp;
      
      startWattDepotTiming();
      if (isVirtual) {
        int powerInt = (int)client.getLatestPowerConsumed(sourceName);
        power = String.valueOf(powerInt);
        // With virtual sources, the timestamp is the time we queried.
        powerTimestamp = gdataService.makeLastUpdate();
      }
      else {
        SensorData data = client.getLatestSensorData(sourceName);
        double powerDouble = data.getPropertyAsDouble("powerConsumed");
        power = String.valueOf((int)powerDouble);
        // With non-virtual sources, the timestamp is the timestamp on the data.
        powerTimestamp = gdataService.makeLastUpdate(data.getTimestamp());
      }
      stopWattDepotTiming();
      
      // Update rolling data only if this data is not already in the rolling data.
      if (!rollingData.getLastTimeStamp().equals(powerTimestamp)) {
        rollingData.add(powerTimestamp, power);
      }
      
      // Now update the spreadsheet.
      startGDataTiming();
      GDataBatchRequest request = new GDataBatchRequest(gdataService, spreadsheetURL);
      // Update the lastUpdate cell
      request.addRequest(this.row, 2, gdataService.makeLastUpdate());
      // Update the remaining columns with the rolling data. 
      int column = 3;
      for (RollingData.Entry entry : rollingData) {
        request.addRequest(this.row, column, entry.lastUpdate);
        column++;
        request.addRequest(this.row, column, entry.data);
        column++;
      }
      request.sendRequest();
      stopGDataTiming();
      printTaskResults(power, "watts", powerTimestamp);
    }
    catch (Exception e) {
      System.out.format("Problem retrieving power for source %s: %s%n", sourceName, e.getMessage());
      e.printStackTrace();
    }
  }
}
